#ifndef SYSTEM_API_H
#define SYSTEM_API_H

// #include <stdio.h>
#include "stdio.h"





#ifdef __cplusplus
extern "C"
{
#endif
//#include "stdio.h"
#include "master.h"
#include "upv.h"
#include "rtk.h"
#include "din.h"
    /****************************** Thread Func **********************************/
    /* struct used for dynamic thread creation on RTK */
    typedef void*(*MbbmsTaskFunc)(void *);

    typedef struct
    {
        t_MsgHeader RtkMsgHeader; /* RTK msg header */
        MbbmsTaskFunc   TaskFunction; /* MBBMS task entry func */
        void*       TaskFunctionParam; /* MBBMS task entry func's param */
    } MbbmsTskMsg;


    void *GetPID();

    void InitializeThread();
    void UninitializeThread();

    /* Obtain the identifier of the current thread.  */
    void *ThreadSelf();

    /* Create a new thread, starting with execution of START-ROUTINE
       getting passed ARG.  Creation attributed come from ATTR.  The new
       handle is stored in *NEWTHREAD.  */
    int ThreadCreate(void **pThreadHandler,
                     void *(*startFunc)(void *), void *thisData);

    /* Create a new thread with a name, starting with execution of START-ROUTINE
       getting passed ARG.  Creation attributed come from ATTR.  The new
       handle is stored in *NEWTHREAD.  */
    int ThreadCreateEx(const char *threadName, void **pThreadHandler,
                       void *(*startFunc)(void *), void *thisData);

    /* Destroy the resources of the thread. */
    int ThreadDestroy(void **pThreadHandler);

    /* Terminate calling thread.

       The registered cleanup handlers are called via exception handling
       so we cannot mark this function with __THROW.*/
    void ThreadExit(void *pReturnValue);

    /* Make calling thread wait for termination of the thread TH.  The
       exit status of the thread is stored in *THREAD_RETURN, if THREAD_RETURN
       is not NULL.

       This function is a cancellation point and therefore not marked with
       __THROW.  */
    int ThreadJoin(void **pThreadHandler, void **data);


    /* Mutex handling.  */

    /* Initialize a mutex.  */
    int ThreadMutexInit(void **pMutexHandler);

    /* Destroy a mutex.  */
    int ThreadMutexDestroy(void **pMutexHandler);

    /* Try locking a mutex.  */
    int ThreadMutexTrylock(void **pMutexHandler);

    /* Lock a mutex.  */
    int ThreadMutexLock(void **pMutexHandler);

    /* Unlock a mutex.  */
    int ThreadMutexUnlock(void **pMutexHandler);


    /* Functions for handling conditional variables.  */

    /* Initialize condition variable COND using attributes ATTR, or use
       the default values if later is NULL.  */
    int ThreadCondInit(void **pCondHandler);

    /* Destroy condition variable COND.  */
    int ThreadCondDestroy(void **pCondHandler);

    /* Wake up one thread waiting for condition variable COND.  */
    int ThreadCondSignal(void **pCondHandler);

    /* Wait for condition variable COND to be signaled or broadcast.
       MUTEX is assumed to be locked before.

       This function is a cancellation point and therefore not marked with
       __THROW.  */
    int ThreadCondWait(void **pCondHandler, void **pMutexHandler);

    void threadCondUninit(void);
    void AtomicInit(volatile void *pAtomic);

    /**
     * atomic_inc - increment atomic variable
     * @v: pointer of type atomic_t
     *
     * Atomically increments @v by 1.
     */
    void AtomicInc(volatile void *pAtomic);

    /**
     * atomic_dec - decrement atomic variable
     * @v: pointer of type atomic_t
     *
     * Atomically decrements @v by 1.
     */
    void AtomicDec(volatile void *pAtomic);


    /**
     * atomic_dec_and_test - decrement and test
     * @v: pointer of type atomic_t
     *
     * Atomically decrements @v by 1 and
     * returns true if the result is 0, or false for all other
     * cases.
     */
    int AtomicDecAndTest(volatile void *pAtomic);

#ifndef ATOMIC_STRUCT_SIZE
#define ATOMIC_STRUCT_SIZE 4
#endif

    void SysPrintf(const char *format, ...);

    void SysPrint2File(const char *filename, const char *format, ...);

    // Uncompress the given in file to the given out file.
    int UncompressGZipFile(const char *infile, const char *outfile);


    /**
     * Time.
     */
#include <time.h>

    // Get current time.
    time_t Time(time_t *t);

    // Convert time_t to struct tm.
    struct tm *LocalTime(time_t *t);

    // Convert struct tm to time_t.
    time_t MkTime(struct tm *t);


    /**
     * File system.
     */
    // Judge if a file exists, can be readed and writen.
    int AccessReadWrite(const char * pathname);

    // Change file name or path.
    int ReName(const char *oldpath, const char *newpath);

    // Delete a file.
    int Unlink(const char * pathname);

    // Truncate a file to designated size.
    int Truncate(const char * path, unsigned long length);

    FILE *FReOpen(const char *path, const char *mode, FILE *stream);

    int CreatePath(const char *pathname);
    int FsOpen(const char * pathname, int flags);

    int FsRead(int fd, void *buf, unsigned int count);

    int FsWrite(int fd, const void *buf, unsigned int count);

    int FsLseek(int fildes, int offset, int whence);

    int FsClose(int fd);

    /**
     * Memory.
     */
    void* MemMalloc(unsigned int size);
    void* MemRealloc(void *ptr, unsigned int size);
    void MemFree(void *ptr);
    void* MemMemmove(void *dest, const void *src, unsigned int n);
#define T3G
#ifdef T3G
    enum {
        MBBMS_EVENT_TYPE_UNDEFINED,
        MBBMS_EVENT_TYPE_TIMEOUT,
        MBBMS_EVENT_TYPE_SOCKET_CONNECTED,
        MBBMS_EVENT_TYPE_SOCKET_DATAREAD,
        MBBMS_EVENT_TYPE_SOCKET_BUFFERFREE,
        MBBMS_EVENT_TYPE_GPRS_CONNECTED
    };

    typedef struct
    {
        unsigned int type;
        unsigned int timerID;
        unsigned int waitingTskId;
        unsigned int is_waiting;
    } MbbmsEvent;


    int ThreadEventInit(void **pEventHandler);
    int ThreadEventDestroy(void **pEventHandler);
    int ThreadEventSignal(void **pEventHandler);
    int ThreadEventWait(void **pEventHandler, unsigned int timeout);
    unsigned int mbbms_get_active_task();

#endif

#ifdef __cplusplus
}
#endif

#endif
